package com.runvp.handler;

import com.alibaba.fastjson.JSONObject;
import com.runvp.common.constant.ConstantRedisKey;
import com.runvp.common.core.redis.DistributeRedisLock;
import com.runvp.common.core.redis.RedisCache;
import com.runvp.common.core.redis.RedisLockClient;
import com.runvp.common.enums.CargoUseStatus;
import com.runvp.common.enums.NettyCmd;
import com.runvp.common.enums.NettyType;
import com.runvp.common.enums.OrderStatus;
import com.runvp.common.model.tcp.MessageReceiveBody;
import com.runvp.common.model.tcp.MessageResBody;
import com.runvp.common.util.BigDecimalUtil;
import com.runvp.common.util.ToolUtils;
import com.runvp.common.utils.DateUtils;
import com.runvp.common.utils.StringUtils;
import com.runvp.service.biz.domain.BizOrder;
import com.runvp.service.biz.handler.CmdCommonHandler;
import com.runvp.service.tcp.TcpService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;

@Slf4j
@Component
public class CmdDeviceChargEndHandler {

    @Autowired
    private RedisCache redisCache;
    @Autowired
    private RedisLockClient lockClient;
    @Autowired
    private CmdCommonHandler cmdCommonHandler;
    @Autowired
    private TcpService tcpService;
    /**
     * 设备充电结束上报
     * @param parseBody
     * @return MessageResBody
     */
    public MessageResBody handle(MessageReceiveBody parseBody){
        log.info("设备充电结束上报信息处理:::receiveBody:{}",JSONObject.toJSONString(parseBody));
        String batchNo = System.nanoTime()+"";
        String sn = parseBody.getTerminalId();
        long id = ToolUtils.objTOLong(tcpService.instanceRedisUtil().getCacheObject(ConstantRedisKey.DEVICE_SN_ID+sn));
        tcpService.addBizTcpRecord(parseBody.setBatchNo(batchNo));
        JSONObject body = parseBody.getBodyJson();
        //处理结束充电逻辑
        handleEndBody(body);
        String oid = body.getString("oid");
        MessageResBody resBody = buildRes(oid);
        resBody.setDeviceId(id);
        resBody.setTerminalId(sn);
        tcpService.addBizTcpRecord(resBody.setBatchNo(batchNo));
        log.info("设备充电结束上报信息处理:::resBody:{}",JSONObject.toJSONString(resBody));
        return resBody;
    }

    /**
     * 订单结束处理
     * @param body
     */
    private void handleEndBody(JSONObject body){
        String oid = body.getString("oid");
        if(StringUtils.isBlank(oid)){
            log.warn("oid为空，停止执行");
            return;
        }
        DistributeRedisLock redisLock = lockClient.getRedisLock("endOrder:"+oid);
        try {
            redisLock.lock();
            BizOrder order = tcpService.instanceIBizOrderService().selectBizOrderByOrderNo(oid);
            if(null == order){
                tcpService.instanceIBizDeviceCargoService().usePort(ToolUtils.objTOLong(oid), CargoUseStatus.IDLE.getCode());
                log.info("调试订单【{}】充电结束,端口释放成功,执行结束",oid);
                return;
            }
            BigDecimal amt = body.getBigDecimal("amt");
            order.setFee(amt);
            order.setRe(body.getInteger("re"));
            order.setOa(body.getBigDecimal("oa"));
            order.setAmount(BigDecimalUtil.sub(order.getAmount(),amt));
            order.setPayAmount(order.getAmount());
            order.setDur(body.getInteger("dur"));
            order.setQty(body.getBigDecimal("qty"));
            order.setSrt(body.getString("srt"));
            order.setEnt(body.getString("ent"));
            order.setSuccessTime(new Date());
//            tcpService.instanceIBizOrderService().updateBizOrder(order);
            log.info("订单【{}】当前状态【{}】",oid,order.getStatus());
            if(!OrderStatus.GO_ON.getCode().equals(order.getStatus())){
                log.info("订单【{}】不是进行中状态,执行结束",oid);
                return;
            }
            order.setStatus(OrderStatus.COMPLETED.getCode());
            String msg = String.format("\n时间【%s】充电结束", DateUtils.getTime());
            order.setRemark(order.getRemark()+msg);
            //订单退款结算
            BizOrder refund = new BizOrder();
            refund.setOrderNo(oid);
            refund.setAmount(amt);
            refund.setCustomerId(order.getCustomerId());
            refund.setType(order.getType());
            refund.setCreateBy(order.getCreateBy());
            cmdCommonHandler.buildCustomerRefundTranLog("充电结束退款: ",refund);
            String over = String.format("\n时间【%s】订单完成结算(本次共消费【%s】元,退回账户【%s】元)", DateUtils.getTime(),order.getAmount(),amt);
            order.setRemark(order.getRemark()+over);
            tcpService.instanceIBizOrderService().updateBizOrder(order);
            log.info("【{}】订单结束,结算处理成功",oid);
            tcpService.instanceIBizDeviceCargoService().usePort(order.getCargoId(), CargoUseStatus.IDLE.getCode());
            log.info("【{}】订单结束,端口释放成功",oid);
        }catch (Exception e){
            log.error("【{}】订单结束处理异常:{}",oid,e.getMessage());
        }finally {
            redisLock.unlock();
        }

    }
    /**
     * 默认报文
     *
     * @return MessageResBody
     */
    public MessageResBody buildRes(String oid) {
        MessageResBody resBody = new MessageResBody(NettyType.SERVER_RECEIVE_DEVICE.getCode(), NettyCmd.SERVER_RES_CHARG_END_REPORT.getCode());
        resBody.setDid("000000000000");
        resBody.setVersion("01");
        resBody.setBodyJson(buildBody(oid)).buildRes();
        return resBody;
    }

    /**
     * 结构结果体
     * @return str
     */
    private JSONObject buildBody(String oid){
        JSONObject map = new JSONObject();
        map.put("oid",oid);
        return map;
    }

}
